<script setup>
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { onBeforeMount, onBeforeUnmount, onMounted, ref } from 'vue'
import { createEv, editorOption } from './editorOption'
import {removeSpacesAndNewlines} from "../../common/util.js"

const props = defineProps({
  lang: {
    type: String,
    default: 'javascript',
  },
  modelValue: {
    type: String,
    default: '',
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
  regex: {
    type: String,
    default: false,
  }
})
const emits = defineEmits(['update:modelValue'])
const editorRef = ref()
const editorModel = monaco.editor.createModel('', props.lang)
let editorInstance = null

onBeforeMount(() => {
  createEv()
})

onMounted(() => {
  const option = Object.assign({}, editorOption, {
    value: props.modelValue,
    model: editorModel,
    readOnly: props.readOnly,
  })
  setTimeout(() => {
    editorInstance = monaco.editor.create(editorRef.value, option)
    editorInstance.setValue(props.modelValue)
    editorInstance.onDidBlurEditorText(apply)
    let previousContent = editorModel.getValue()
    editorInstance.onDidChangeModelContent(event => {
      if(!props.regex) return
      const regex = new RegExp(props.regex)
      event.changes.forEach(change => {
        // 获取更改后的整个模型内容
        const currentContent = editorModel.getValue();
        // 检查当前内容是否符合正则表达式
        if (!regex.test(removeSpacesAndNewlines(currentContent))) {
          // 如果内容不符合正则表达式，则撤销到上一次保存的状态
          editorInstance.executeEdits('', [
            {
              range: editorModel.getFullModelRange(),
              text: previousContent
            }
          ]);
          console.warn('禁止更改预设格式');
        } else {
          // 如果内容符合正则表达式，则更新保存的内容
          previousContent = currentContent;
        }
      });
    })
  }, 0)

})

function apply() {
  emits('update:modelValue', editorInstance.getValue())
}

function dispose() {
  editorInstance.dispose()
}

onBeforeUnmount(() => {
  dispose()
})

defineExpose({apply, dispose})
</script>

<template>
  <div class="editor-container-box">
    <div ref="editorRef" class="editor-container" tabindex="999" @keydown.ctrl.s.prevent="apply"></div>
  </div>
</template>

<style scoped>
.editor-container-box {
  width: 100%;
  height: 100%;
  position: relative;
  min-height: 25px;
}
.editor-container {
  width: 100%;
  height: 100%;
  min-height: 25px;
}
.editor-container-btn {
  position: absolute;
  bottom: 2px;
  right: 2px;
}
</style>
